﻿using BZ.Core;
using NDK.AcqDevice;
using DllSampleAll;
using LJV7_DllSampleAll;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using NDK.Laser;

namespace NDK.AcqDevice.Keyence
{
    public class Laser_CL3 : IDevice, IPointLaser
    {
        string _IP = "192.168.10.10";
        private const int MaxRequestDataLength = 512000;

        public event PropertyChangedEventHandler PropertyChanged;
        private string _status = string.Empty;
        public string Status
        {
            get
            {
                return _status;
            }
            private set
            {
                _status = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(value.ToString()));
            }
        }
        public string IP
        {
            get
            {
                return _IP;
            }

            set
            {
                _IP = value;
            }
        }
        public Laser_CL3(string IP)
        {
            _IP = IP;
        }

        public bool Open()
        {
            try
            {
                Status = $"PointLaser （通讯口{IP}) Connecting...";
                CL3IF_ETHERNET_SETTING ethernetSetting = new CL3IF_ETHERNET_SETTING();
                ethernetSetting.ipAddress = new byte[4];
                string[] IPs = _IP.Split('.');
                if (!byte.TryParse(IPs[0], out ethernetSetting.ipAddress[0]))
                {
                    return false;
                }
                if (!byte.TryParse(IPs[1], out ethernetSetting.ipAddress[1]))
                {
                    return false;
                }
                if (!byte.TryParse(IPs[2], out ethernetSetting.ipAddress[2]))
                {
                    return false;
                }
                if (!byte.TryParse(IPs[3], out ethernetSetting.ipAddress[3]))
                {
                    return false;
                }
                //if (!ushort.TryParse(Port.getString(), out ethernetSetting.portNo))
                //{
                //    return false;
                //}

                ethernetSetting.reserved = new byte[2];
                ethernetSetting.reserved[0] = 0x00;
                ethernetSetting.reserved[1] = 0x00;
                int returnCode = NativeMethods_CL3_IF.CL3IF_OpenEthernetCommunication(0, ref ethernetSetting, 10000);

            }
            catch (Exception ex)
            {
                Status = $"PointLaser （通讯口{IP}) CL3IF_OpenEthernetCommunication  Exception Message:{ex.Message} Exception StackTrace {ex.StackTrace}";
                throw new LaserException($"CL3IF_OpenEthernetCommunication Exception! Exception Message:{ex.Message} Exception StackTrace {ex.StackTrace} ");

            }
            return true;
        }
        private List<CL3IF_OUTMEASUREMENT_DATA> Read()
        {
            List<CL3IF_OUTMEASUREMENT_DATA> datalist = new List<CL3IF_OUTMEASUREMENT_DATA>(0);
            byte[] buffer = new byte[MaxRequestDataLength];
            try
            {
                using (PinnedObject pin = new PinnedObject(buffer))
                {
                    CL3IF_MEASUREMENT_DATA measurementData = new CL3IF_MEASUREMENT_DATA();
                    measurementData.outMeasurementData = new CL3IF_OUTMEASUREMENT_DATA[NativeMethods_CL3_IF.CL3IF_MAX_OUT_COUNT];

                    int returnCode = NativeMethods_CL3_IF.CL3IF_GetMeasurementData(0, pin.Pointer);
                    if (returnCode != NativeMethods_CL3_IF.CL3IF_RC_OK)
                    {
                        return null;
                    }

                    measurementData.addInfo = (CL3IF_ADD_INFO)Marshal.PtrToStructure(pin.Pointer, typeof(CL3IF_ADD_INFO));
                    int readPosition = Marshal.SizeOf(typeof(CL3IF_ADD_INFO));
                    for (int i = 0; i < NativeMethods_CL3_IF.CL3IF_MAX_OUT_COUNT; i++)
                    {
                        measurementData.outMeasurementData[i] = (CL3IF_OUTMEASUREMENT_DATA)Marshal.PtrToStructure(pin.Pointer + readPosition, typeof(CL3IF_OUTMEASUREMENT_DATA));
                        readPosition += Marshal.SizeOf(typeof(CL3IF_OUTMEASUREMENT_DATA));
                    }


                    datalist.Add(measurementData.outMeasurementData[0]);
                    datalist.Add(measurementData.outMeasurementData[1]);
                    datalist.Add(measurementData.outMeasurementData[2]);
                    datalist.Add(measurementData.outMeasurementData[3]);
                    datalist.Add(measurementData.outMeasurementData[4]);
                    datalist.Add(measurementData.outMeasurementData[5]);
                    datalist.Add(measurementData.outMeasurementData[6]);
                    datalist.Add(measurementData.outMeasurementData[7]);
                }
            }
            catch (Exception ex)
            {
                Status = $"PointLaser （通讯口{IP}) CL3IF_GetMeasurementData  Exception Message:{ex.Message} Exception StackTrace {ex.StackTrace}";
                throw new LaserException($"CL3IF_GetMeasurementData Exception!StackTrace:{ex.StackTrace} ");
            }

            return datalist;
        }
        public List<double> ReadAll()
        {
            List<double> datalist = new List<double>(0);
            List<CL3IF_OUTMEASUREMENT_DATA> list = Read();
            foreach (var val in list)
            {
                datalist.Add(val.measurementValue / 10000.0);
            }

            return datalist;
        }

        /// <summary>
        /// 读取指定通道的值，超时时间未使用
        /// </summary>
        /// <param name="index"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public string Read(int index,int timeout=int.MaxValue)
        {

            List<CL3IF_OUTMEASUREMENT_DATA> list = Read();
            string ret = (list[index]).ToString();
            Status = $"PointLaser （通讯口{IP})， Chanel {index}， Value：{ret}";

            return ret;

        }

    }
}
